package com.cgw.game.ui;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.cgw.game.R;
import com.cgw.game.utils.ImageProcessing;
import com.cgw.game.view.MyLineChart;
import com.cgw.game.view.MyLineChartRenderer;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

public class CameraHeartActivity extends AppCompatActivity {

    MyLineChart chart;

    private PowerManager.WakeLock wakeLock;
    private TextView text,text1;
    //Android手机预览控件
    private SurfaceView preview;
    //预览设置信息
    private  SurfaceHolder previewHolder;
    private  Camera camera;


    private static int gx;
    private static int j;
    private static double flag=1;


    private static int averageIndex = 0;
    private static final int averageArraySize = 4;
    private static final int[] averageArray = new int[averageArraySize];

    private static final AtomicBoolean processing = new AtomicBoolean(false);
    public enum TYPE {
        GREEN, RED
    }
    //设置默认类型
    private static TYPE currentType = TYPE.GREEN;
    //获取当前类型
    public static TYPE getCurrent() {
        return currentType;
    }
    //心跳下标值
    private static int beatsIndex = 0;
    //心跳数组的大小
    private static final int beatsArraySize = 3;
    //心跳数组
    private static final int[] beatsArray = new int[beatsArraySize];
    //心跳脉冲
    private static double beats = 0;
    //开始时间
    private static long startTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_heart);
        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle(getIntent().getStringExtra("title"));
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);//左侧添加一个默认的返回图标
        getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();//返回
            }
        });
        initView();
    }

    @SuppressLint("InvalidWakeLockTag" )
    private void initView() {
        chart = findViewById(R.id.chart);
        initChart();
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
        preview = findViewById(R.id.preview);
        previewHolder = preview.getHolder();
        previewHolder.addCallback(surfaceCallback);
        previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        text = findViewById(R.id.text);
        text1 =findViewById(R.id.text1);
    }
    /**
    * 初始化图表
    */
    private void initChart() {
        chart.setExtraBottomOffset(5f);
//        chart3Line.getAxisLeft().setDrawGridLines(false);
        chart.setTouchEnabled(true);
        chart.setPinchZoom(false);
        chart.setScaleYEnabled(false);
        chart.setDragEnabled(true);
        chart.setDoubleTapToZoomEnabled(false);
        chart.getViewPortHandler().setMaximumScaleX(5.0f);
        //取消说明
        chart.getLegend().setEnabled(false);
        chart.getDescription().setEnabled(false);
        chart.setNoDataText("暂无数据");
        chart.setVisibleXRangeMaximum(5);

        YAxis leftAxis = chart.getAxisLeft();
        leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
        leftAxis.setTextSize(12f);
        leftAxis.setTextColor(Color.parseColor("#91a2a3"));
//      leftAxis.setValueFormatter(new PercentFormatter());
//        leftAxis.setValueFormatter(new IndexAxisValueFormatter());
        leftAxis.setEnabled(true);
        leftAxis.setGridColor(Color.parseColor("#e3edf2"));
        leftAxis.setDrawAxisLine(true);
        leftAxis.setAxisMinimum(40f);
        leftAxis.setAxisMaximum(220f);
        leftAxis.setLabelCount(5, true);
        chart.getAxisRight().setEnabled(false);

        //横向轴线设置
        XAxis xAxis = chart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextSize(12f);
        xAxis.setTextColor(Color.parseColor("#91a2a3"));
        xAxis.setEnabled(true);  //是否打开x轴
        xAxis.setDrawGridLines(false);
        xAxis.setAxisMinimum(0f);
        xAxis.setGranularityEnabled(true);
        xAxis.setLabelCount(5, false);
        /*// 转换要显示的标签文本，value值默认是int从0开始
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return famatTime((int) value);
            }
        });*/
        xAxis.setAxisLineColor(Color.parseColor("#e3edf2"));
        //设置为虚线
        xAxis.setDrawAxisLine(true);
    }

    @Override
    public void onResume() {
        super.onResume();
        wakeLock.acquire();
        camera = Camera.open();
    }

    @Override
    public void onPause() {
        super.onPause();
        wakeLock.release();
        camera.setPreviewCallback(null);
        camera.stopPreview();
        camera.release();
        camera = null;
    }


    /**
     * 预览回调接口
     */
    private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
        //创建时调用
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera.setPreviewDisplay(previewHolder);
                camera.setPreviewCallback(previewCallback);
            } catch (Throwable t) {
            }
        }
        //当预览改变的时候回调此方法
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
            Camera.Parameters parameters = camera.getParameters();
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
            Camera.Size size = getSmallestPreviewSize(width, height, parameters);
            if (size != null) {
                parameters.setPreviewSize(size.width, size.height);
                //				Log.d(TAG, "Using width=" + size.width + " height="	+ size.height);
            }
            camera.setParameters(parameters);
            camera.startPreview();
        }
        //销毁的时候调用
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // Ignore
        }
    };

    /**
     * 获取相机最小的预览尺寸
     * @param width
     * @param height
     * @param parameters
     * @return
     */
    private static Camera.Size getSmallestPreviewSize(int width, int height,
                                                      Camera.Parameters parameters) {
        Camera.Size result = null;
        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width <= width && size.height <= height) {
                if (result == null) {
                    result = size;
                } else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;
                    if (newArea < resultArea)
                        result = size;
                }
            }
        }
        return result;
    }

    /**
     * 相机预览方法
     * 这个方法中实现动态更新界面UI的功能，
     * 通过获取手机摄像头的参数来实时动态计算平均像素值、脉冲数，从而实时动态计算心率值。
     */
    private  Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera cam) {
            if (data == null)
                throw new NullPointerException();
            Camera.Size size = cam.getParameters().getPreviewSize();
            if (size == null)
                throw new NullPointerException();
            if (!processing.compareAndSet(false, true))
                return;
            int width = size.width;
            int height = size.height;
            //图像处理
            int imgAvg = ImageProcessing.decodeYUV420SPtoRedAvg(data.clone(),height,width);
            gx=imgAvg;
//            text1.setText("平均像素值是"+String.valueOf(imgAvg));
            //像素平均值imgAvg,日志
            //Log.i(TAG, "imgAvg=" + imgAvg);
            if (imgAvg == 0 || imgAvg == 255) {
                processing.set(false);
                return;
            }
            //计算平均值
            int averageArrayAvg = 0;
            int averageArrayCnt = 0;
            for (int i = 0; i < averageArray.length; i++) {
                if (averageArray[i] > 0) {
                    averageArrayAvg += averageArray[i];
                    averageArrayCnt++;
                }
            }
            //计算平均值
            int rollingAverage = (averageArrayCnt > 0)?(averageArrayAvg/averageArrayCnt):0;
            TYPE newType = currentType;
            if (imgAvg < rollingAverage) {
                newType = TYPE.RED;
                if (newType != currentType) {
                    beats++;
                    flag=0;
                    text1.setText("脉冲数是"+String.valueOf(beats));
                    //Log.e(TAG, "BEAT!! beats=" + beats);
                }
            } else if (imgAvg > rollingAverage) {
                newType = TYPE.GREEN;
            }

            if (averageIndex == averageArraySize)
                averageIndex = 0;
            averageArray[averageIndex] = imgAvg;
            averageIndex++;

            // Transitioned from one state to another to the same
            if (newType != currentType) {
                currentType = newType;
                //image.postInvalidate();
            }
            //获取系统结束时间（ms）
            long endTime = System.currentTimeMillis();
            double totalTimeInSecs = (endTime - startTime) / 1000d;
            if (totalTimeInSecs >= 2) {
                double bps = (beats / totalTimeInSecs);
                int dpm = (int) (bps * 60d);
                if (dpm < 30 || dpm > 180||imgAvg<200) {
                    //获取系统开始时间（ms）
                    startTime = System.currentTimeMillis();
                    //beats心跳总数
                    beats = 0;
                    processing.set(false);
                    return;
                }
                //Log.e(TAG, "totalTimeInSecs=" + totalTimeInSecs + " beats="+ beats);
                if (beatsIndex == beatsArraySize)
                    beatsIndex = 0;
                beatsArray[beatsIndex] = dpm;
                beatsIndex++;
                int beatsArrayAvg = 0;
                int beatsArrayCnt = 0;
                for (int i = 0; i < beatsArray.length; i++) {
                    if (beatsArray[i] > 0) {
                        beatsArrayAvg += beatsArray[i];
                        beatsArrayCnt++;
                    }
                }
                int beatsAvg = (beatsArrayAvg / beatsArrayCnt);
                text.setText("您的的心率是"+String.valueOf(beatsAvg)+"  zhi:"+String.valueOf(beatsArray.length)
                        +"    "+String.valueOf(beatsIndex)+"    "+String.valueOf(beatsArrayAvg)+"    "+String.valueOf(beatsArrayCnt));
                //获取系统时间（ms）
                addEntry(beatsAvg);
                startTime = System.currentTimeMillis();
                beats = 0;
            }
            processing.set(false);
        }
    };

    private void setData(List<Entry> values) {
        if (chart.getRenderer() instanceof MyLineChartRenderer) {
            MyLineChartRenderer renderer = (MyLineChartRenderer) chart.getRenderer();

            int medium = 80;
            int larger = 120;
            int limit = 160;


            int[] colors = new int[4];
            colors[0] = Color.parseColor("#fa7069");
            colors[1] = Color.parseColor("#faa369");
            colors[2] = Color.parseColor("#facd69");
            colors[3] = Color.parseColor("#d3d8dc");

            renderer.setHeartLine(true, medium,larger,limit, colors);
        }
        LineDataSet lineDataSet;
        lineDataSet = new LineDataSet(values, "HOME1");
        lineDataSet.setMode(LineDataSet.Mode.LINEAR);
        lineDataSet.setLabel("Result Scores");
        lineDataSet.setColor(getResources().getColor(R.color.red));
        lineDataSet.setCircleColor(getResources().getColor(R.color.red));
        lineDataSet.setDrawHorizontalHighlightIndicator(false);
        lineDataSet.setHighLightColor(getResources().getColor(R.color.red));
        lineDataSet.enableDashedHighlightLine(10, 10, 0);
        lineDataSet.setFillAlpha(100);
        lineDataSet.setDrawFilled(false);
        lineDataSet.setHighlightLineWidth(1f);
        lineDataSet.setLineWidth(2f);
        lineDataSet.setCircleRadius(3f);
        lineDataSet.setDrawCircleHole(false);
        lineDataSet.setDrawCircles(false);
        lineDataSet.setDrawValues(false);
        LineData lineData = new LineData();
        lineData.addDataSet(lineDataSet);
        chart.setData(lineData);
    }

    public void addEntry(int value) {
        LineData lineData = chart.getLineData();
        if (lineData != null) {
            int count = lineData.getEntryCount();
            lineData.addEntry(new Entry(count,value), 0);
            chart.notifyDataSetChanged();
            chart.invalidate();
            chart.moveViewTo(count, value, YAxis.AxisDependency.LEFT);
        }else {
            List<Entry> values = new ArrayList<>();
            values.add(new Entry(0,value));
            setData(values);
        }
    }
}
